package fr.lip6.move.care;

import com.google.common.base.Objects;
import fr.lip6.move.care.CareGen;
import fr.lip6.move.care.CompileResult;
import fr.lip6.move.care.SDMakerToCareUtils;
import java.util.ArrayList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.xtend2.lib.StringConcatenation;
import sdmakerz_v1.coresyntax.generator.SDMakerV1IDProvider;
import sdmakerz_v1.coresyntax.generator.interfaces.IConfigData;
import sdmakerz_v1.coresyntax.generator.interfaces.IContext;
import sdmakerz_v1.coresyntax.sDMakerV1.CombinableDiagramElement;
import sdmakerz_v1.coresyntax.sDMakerV1.DoubleExp;
import sdmakerz_v1.coresyntax.sDMakerV1.Opt;

@SuppressWarnings("all")
public class CareOptGen {
  private CareGen mainGenerator;
  
  public CareOptGen(final CareGen mainGenerator) {
    this.mainGenerator = mainGenerator;
  }
  
  public CompileResult compile(final IContext context, final Opt opt) {
    IConfigData config = context.getConfigData();
    ArrayList<CompileResult> _arrayList = new ArrayList<CompileResult>();
    ArrayList<CompileResult> nestedResults = _arrayList;
    ArrayList<String> _arrayList_1 = new ArrayList<String>();
    ArrayList<String> nestedEltIDs = _arrayList_1;
    CompileResult compRes = null;
    int _computeID = SDMakerV1IDProvider.computeID();
    String optID = ("opt_id" + Integer.valueOf(_computeID));
    double probExec = (-1);
    boolean _and = false;
    boolean _and_1 = false;
    DoubleExp _probExec = opt.getProbExec();
    boolean _notEquals = (!Objects.equal(_probExec, null));
    if (!_notEquals) {
      _and_1 = false;
    } else {
      DoubleExp _probExec_1 = opt.getProbExec();
      double _value = _probExec_1.getValue();
      boolean _lessThan = (0 < _value);
      _and_1 = (_notEquals && _lessThan);
    }
    if (!_and_1) {
      _and = false;
    } else {
      DoubleExp _probExec_2 = opt.getProbExec();
      double _value_1 = _probExec_2.getValue();
      boolean _lessEqualsThan = (_value_1 <= 1);
      _and = (_and_1 && _lessEqualsThan);
    }
    if (_and) {
      DoubleExp _probExec_3 = opt.getProbExec();
      double _value_2 = _probExec_3.getValue();
      probExec = _value_2;
    } else {
      double _probExecOpt = config.probExecOpt();
      probExec = _probExecOpt;
    }
    StringConcatenation _builder = new StringConcatenation();
    _builder.newLine();
    {
      EList<CombinableDiagramElement> _opts = opt.getOpts();
      for(final CombinableDiagramElement elt : _opts) {
        CompileResult _compile = this.mainGenerator.compile(context, elt);
        CompileResult _compRes = compRes = _compile;
        CharSequence _nullExp = SDMakerToCareUtils.toNullExp(_compRes);
        _builder.append(_nullExp, "");
        _builder.newLineIfNotEmpty();
        boolean _add = nestedResults.add(compRes);
        CharSequence _nullExp_1 = SDMakerToCareUtils.toNullExp(Boolean.valueOf(_add));
        _builder.append(_nullExp_1, "");
        _builder.newLineIfNotEmpty();
        String _eltID = compRes.getEltID();
        boolean _add_1 = nestedEltIDs.add(_eltID);
        CharSequence _nullExp_2 = SDMakerToCareUtils.toNullExp(Boolean.valueOf(_add_1));
        _builder.append(_nullExp_2, "");
        _builder.newLineIfNotEmpty();
      }
    }
    _builder.newLine();
    {
      int _size = nestedEltIDs.size();
      boolean _equals = (_size == 1);
      if (_equals) {
        _builder.append("/* OPT: ");
        _builder.append(optID, "");
        _builder.append(" */");
        _builder.newLineIfNotEmpty();
        _builder.append(" ");
        CompileResult _get = nestedResults.get(0);
        CharSequence _charSequenceResult = _get.getCharSequenceResult();
        _builder.append(_charSequenceResult, " ");
        _builder.newLineIfNotEmpty();
        {
          boolean _and_2 = false;
          boolean _lessThan_1 = (0 < probExec);
          if (!_lessThan_1) {
            _and_2 = false;
          } else {
            boolean _lessEqualsThan_1 = (probExec <= 1);
            _and_2 = (_lessThan_1 && _lessEqualsThan_1);
          }
          if (_and_2) {
            _builder.append("Opt ");
            _builder.append(optID, "");
            _builder.append(" = new Opt(");
            String _get_1 = nestedEltIDs.get(0);
            _builder.append(_get_1, "");
            _builder.append(", ");
            _builder.append(probExec, "");
            _builder.append(");");
            _builder.newLineIfNotEmpty();
          } else {
            _builder.append("Opt ");
            _builder.append(optID, "");
            _builder.append(" = new Opt(");
            String _get_2 = nestedEltIDs.get(0);
            _builder.append(_get_2, "");
            _builder.append(");");
            _builder.newLineIfNotEmpty();
          }
        }
      } else {
        int _size_1 = nestedEltIDs.size();
        boolean _greaterThan = (_size_1 > 1);
        if (_greaterThan) {
          _builder.append("/* OPT: ");
          _builder.append(optID, "");
          _builder.append(" */");
          _builder.newLineIfNotEmpty();
          _builder.append("BlockList bloc_");
          _builder.append(optID, "");
          _builder.append(" = new BlockList();");
          _builder.newLineIfNotEmpty();
          {
            for(final CompileResult nestedResult : nestedResults) {
              CharSequence _charSequenceResult_1 = nestedResult.getCharSequenceResult();
              _builder.append(_charSequenceResult_1, "");
              _builder.newLineIfNotEmpty();
            }
          }
          _builder.newLine();
          _builder.append("//add(s) for bloc_");
          _builder.append(optID, "");
          _builder.newLineIfNotEmpty();
          {
            for(final String eltID : nestedEltIDs) {
              _builder.append("bloc_");
              _builder.append(optID, "");
              _builder.append(".add(");
              _builder.append(eltID, "");
              _builder.append(");");
              _builder.newLineIfNotEmpty();
            }
          }
          _builder.newLine();
          _builder.append("/* FINALIZING ");
          _builder.append(optID, "");
          _builder.append(" */");
          _builder.newLineIfNotEmpty();
          {
            boolean _and_3 = false;
            boolean _lessThan_2 = (0 < probExec);
            if (!_lessThan_2) {
              _and_3 = false;
            } else {
              boolean _lessEqualsThan_2 = (probExec <= 1);
              _and_3 = (_lessThan_2 && _lessEqualsThan_2);
            }
            if (_and_3) {
              _builder.append("Opt ");
              _builder.append(optID, "");
              _builder.append(" = new Opt(bloc_");
              _builder.append(optID, "");
              _builder.append(", ");
              _builder.append(probExec, "");
              _builder.append(");");
              _builder.newLineIfNotEmpty();
            } else {
              _builder.append("Opt ");
              _builder.append(optID, "");
              _builder.append(" = new Opt(bloc_");
              _builder.append(optID, "");
              _builder.append(");");
              _builder.newLineIfNotEmpty();
            }
          }
        }
      }
    }
    CharSequence charSequenceResult = _builder;
    CompileResult _compileResult = new CompileResult(charSequenceResult, optID, 
      true);
    return _compileResult;
  }
}
